package cqrtplm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hustcad.plm.basic.util.TyplmEntityBaseUtil;
import com.hustcad.plm.pdm.classification.model.dto.TyplmClassificationEntityDTO;
import com.hustcad.plm.pdm.classification.model.dto.TyplmClassificationQueryTreeDTO;
import com.hustcad.plm.pdm.classification.model.vo.TyplmClassificationEntityTreeVO;
import com.hustcad.plm.pdm.classification.service.TyplmClassificationRootService;
import com.hustcad.plm.pdm.classification.service.TyplmClassificationService;
import com.hustcad.plm.pdm.common.util.CommonUtil;
import com.hustcad.plm.pdm.iba.model.dto.AttributeDefDTO;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeDefService;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.type.model.vo.TypeTree;
import com.hustcad.plm.pdm.type.service.TyplmTypeService;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.entity.type.ClassificationDO;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import com.ty.basic.vo.AttributeVO;
import cqrtplm.config.ConfigurableAttrCardsConfig;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.dto.AttributeCardDTO;
import cqrtplm.dto.ClassificationDTO;
import cqrtplm.dto.FlexibleMatchDTO;
import cqrtplm.dto.RTAttributeCardDTO;
import cqrtplm.dto.query.QueryAttributeCardDTO;
import cqrtplm.entity.RTAttributeCardDO;
import cqrtplm.mapper.RTAttributeCardMapper;
import cqrtplm.mapper.RTEngraveMapper;
import cqrtplm.mapper.RTPartMapper;
import cqrtplm.mapper.RTTypeClassMapper;
import cqrtplm.service.RTAttributeCardService;
import cqrtplm.vo.DrawingCodeVO;
import cqrtplm.vo.RTCodeVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RTAttributeCardServiceImpl implements RTAttributeCardService {

    @Resource
    private RTAttributeCardMapper rtAttributeCardMapper;
    @Resource
    private ConfigurableAttrCardsConfig configurableAttrCardsConfig;
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;
    @Resource
    private RTEngraveMapper rtEngraveMapper;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private TyplmAttributeDefService typlmAttributeDefService;
    @Resource
    private TyplmClassificationService typlmClassificationService;
    @Resource
    private RTPartMapper rtPartMapper;
    @Resource
    private TyplmTypeService typlmTypeService;
    @Resource
    private TyplmClassificationRootService typlmClassificationRootService;
    @Resource
    private RTTypeClassMapper rtTypeClassMapper;
    @Resource
    private TyplmPartService typlmPartService;

    @Value("${rt.attrcard.typeoid}")
    private String typeOId;

    @Override
    public Map<String, Object> queryAttrCardDetail() {
        Map<String, Object> params = new HashMap<>();
        params.put(RTPlmConstant.TYPE,configurableAttrCardsConfig.getTypes());
        // 获取分类码
        List<String> categoryList = rtAttributeCardMapper.queryProjectLine("产品分类");

        // 获取产品型谱下所有零部件OID
        List<BigInteger> partOidList =rtPartMapper.selectAllProductSpectrumByClassName("ProductSpecification");
        List<List<BigInteger>> partOidListList = CommonUtil.subObjectList(partOidList, 999);
        Map<String, List<AttributeVO>> partIbaMap = new HashMap<>();

        for (List<BigInteger> list : partOidListList) {
            Map<String, List<AttributeVO>> map = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                    list,
                    TableTypeConstrant.TY_PART_OTYPE,
                    Arrays.asList(RTPlmConstant.DEVELOPMENT, "ProductSeries", "productType"));
            if(CollUtil.isNotEmpty(map)){
                partIbaMap.putAll(map);
            }
        }
        Map<String,String> devCodeAndProductSeriesMap = new HashMap<>();
        Map<String,String> devCodeAndProductTypeMap = new HashMap<>();
        for (String partOid : partIbaMap.keySet()) {
            List<AttributeVO> attributeVOS = partIbaMap.get(partOid);
            String devCode = "";
            String productSeries = "";
            String productType = "";
            for (AttributeVO attributeVO : attributeVOS) {
                if (RTPlmConstant.DEVELOPMENT.equals(attributeVO.getAttributeEnName())) {
                    devCode = StringUtils.isBlank(attributeVO.getAttributeValuex()) ? attributeVO.getAttributeValue()
                            : attributeVO.getAttributeValuex();
                } else if ("ProductSeries".equals(attributeVO.getAttributeEnName())) {
                    productSeries = StringUtils.isBlank(attributeVO.getAttributeValuex()) ? attributeVO.getAttributeValue()
                            : attributeVO.getAttributeValuex();
                } else if ("productType".equals(attributeVO.getAttributeEnName())) {
                    productType = StringUtils.isBlank(attributeVO.getAttributeValuex()) ? attributeVO.getAttributeValue()
                            : attributeVO.getAttributeValuex();
                }
            }
            if (StringUtils.isNotEmpty(devCode) && StringUtils.isNotBlank(devCode)) {
                devCodeAndProductSeriesMap.put(devCode, productSeries);
                devCodeAndProductTypeMap.put(devCode, productType);
            }
        }
        Map<String, String> sortedDevCodeAndProductSeriesMap = devCodeAndProductSeriesMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new
                ));

        List<String> sortCategoryList = categoryList.stream()
                .sorted()
                .collect(Collectors.toList());

        // 获取产品线
        List<String> prodLineList = rtAttributeCardMapper.queryProductLine();

        params.put(RTPlmConstant.DEVELOPMENTORDER,sortedDevCodeAndProductSeriesMap);
        params.put(RTPlmConstant.CATEGORY, sortCategoryList);
        params.put("devCodeAndProductType", devCodeAndProductTypeMap);
        params.put(RTPlmConstant.PRODUCTLINE, prodLineList);
        log.info("属性卡片详情：{}",params);
        return params;
    }


    @Override
    public RTAttributeCardDTO queryAttrCardDetailTWO() {
        RTAttributeCardDTO rtAttributeCardDTO = new RTAttributeCardDTO();
        rtAttributeCardDTO.setAttributes(new HashMap<>());
        Map<String, List<String>> attributes = rtAttributeCardDTO.getAttributes();
        attributes.put(RTPlmConstant.TYPE,configurableAttrCardsConfig.getTypes());
        List<String> categoryList = rtAttributeCardMapper.queryProjectLine("产品分类");
        List<BigInteger> partOIds =rtEngraveMapper.selectIbaAttr("产品分类");
        Map<String, List<AttributeVO>> ibaMaps = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                partOIds,
                TableTypeConstrant.TY_PART_OTYPE,
                Collections.singletonList(RTPlmConstant.DEVELOPMENT));
        List<String> DevelopmentOrders = ibaMaps.values().stream()
                .flatMap(List::stream)
                .map(AttributeVO::getAttributeValue)
                .filter(attributeValue -> StringUtils.isNotEmpty(String.valueOf(attributeValue)))
                .distinct()
                .collect(Collectors.toList());
        attributes.put(RTPlmConstant.DEVELOPMENTORDER,DevelopmentOrders);
        attributes.put(RTPlmConstant.CATEGORY, categoryList);
        return rtAttributeCardDTO;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insert(RTAttributeCardDTO dto) {
        RTAttributeCardDO rtAttributeCard = BeanUtil.toBean(dto, RTAttributeCardDO.class);
        String type = dto.getType();
        String oid = dto.getAttributeCard();
        switch ( type) {
            case "EBOM号":
                if(StringUtils.isNotBlank(dto.getDevelopmentOrder()) && StringUtils.isNotBlank(dto.getDevelopmentOrder())){
                    List<RTAttributeCardDO> ebomCardFirst = rtAttributeCardMapper.findEBOMCardFirst(type,
                                                                                                    dto.getDevelopmentOrder());
                    if(CollUtil.isNotEmpty(ebomCardFirst)){
                        throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("属性卡片规则重复，请重新选择");
                    }
                    List<String> classIdList = rtPartMapper.selectClassIdPartNumberFix(dto.getDevelopmentOrder(),"EBOM_NUM");
                    if(CollUtil.isNotEmpty(classIdList)  && classIdList.size() > 1){
                        throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("当前所选开发令存在实例化对象的卡片包含多个，不可以新增，请重新选择");
                    } else if(CollUtil.isNotEmpty(classIdList)  && classIdList.size() == 1){
                        String s = classIdList.get(0);
                        if(!s.equals(oid)){
                            throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("该属性卡片与已存在实例化对象的卡片不一致，不可以新增，请重新选择");
                        }
                    }
                } else {
                    Integer count = rtAttributeCardMapper.getDistinctByType(rtAttributeCard);
                    if (count > 0) {
                        throw  RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("属性卡片规则重复，请重新选择");
                    }
                }
                break;
            case "图样代号":
                if(StringUtils.isNotEmpty(dto.getCategory()) && StringUtils.isNotBlank(dto.getCategory())) {
                    List<RTAttributeCardDO> drawingCardFirst = rtAttributeCardMapper.designCodeFindMatchOne(type,
                                                                                                            dto.getCategory(),
                                                                                                            dto.getDevelopmentOrder());
                    if (CollUtil.isNotEmpty(drawingCardFirst)) {
                        throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("属性卡片已经存在，请重新选择");
                    }
                    List<String> classIdList = rtPartMapper.selectClassIdPartNumberFix2(dto.getCategory(), "PatternCode", "devCode", dto.getDevelopmentOrder());
                    if (CollUtil.isNotEmpty(classIdList) && classIdList.size() > 1) {
                        throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("当前所选开发令存在实例化对象的卡片包含多个，不可以新增，请重新选择");
                    } else if (CollUtil.isNotEmpty(classIdList) && classIdList.size() == 1) {
                        String s = classIdList.get(0);
                        if (!s.equals(oid)) {
                            throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("该属性卡片与已存在实例化对象的卡片不一致，不可以新增，请重新选择");
                        }
                    } else {
                        Integer count = rtAttributeCardMapper.getDistinctByType(rtAttributeCard);
                        if (count > 0) {
                            throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("属性卡片规则重复，请重新选择");
                        }
                    }
                }else {
                    throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("请选择产品分类");
                }
                break;
            case "标准件":
                if(StringUtils.isNotEmpty(dto.getCategory()) && StringUtils.isNotBlank(dto.getCategory())){
                    List<RTAttributeCardDO> stdCards = rtAttributeCardMapper.queryAttrCardByCategory(dto.getCategory(), type);
                    if(CollUtil.isNotEmpty(stdCards)){
                        throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("属性卡片规则重复，请重新选择");
                    }
                    List<String> classIdList = rtPartMapper.selectClassIdPartNumberFix(dto.getCategory(),"Standard");
                    if(CollUtil.isNotEmpty(classIdList)  && classIdList.size() > 1){
                        throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("该属性卡片已存在实例化对象，不可以新增，请重新选择");
                    } else if(CollUtil.isNotEmpty(classIdList)  && classIdList.size() == 1){
                        String s = classIdList.get(0);
                        if(!s.equals(oid)){
                            throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("该属性卡片与已存在实例化对象的卡片不一致，不可以新增，请重新选择");
                        }
                    }
                }else {
                    throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("请选择产品分类");
                }
            default:
        }
        //属性卡片判重
//        Integer count = rtAttributeCardMapper.getDistinctByType(rtAttributeCard);
//        if (count > 0) {
//           throw  RTErrorCodeEnum.ATTRIBUTE_CARD_DUPLICATION.getException("属性卡片规则重复，请重新选择");
//        }
        rtAttributeCard.setOid(snowflakeIdComponent.getInstance().nextId());
        TyplmEntityBaseUtil.fillCommonFieldForCreate(rtAttributeCard);
        rtAttributeCardMapper.insert(rtAttributeCard);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAttrCard(RTAttributeCardDTO rtAttributeCardDTO) {
        RTAttributeCardDO rtAttributeCard = BeanUtil.toBean(rtAttributeCardDTO, RTAttributeCardDO.class);
        RTAttributeCardDO currentDo = rtAttributeCardMapper.selectByPrimaryKey(rtAttributeCard.getOid());
        checkIsCanUpdateOrDelete(currentDo);
        TyplmEntityBaseUtil.fillCommonFieldForCreate(rtAttributeCard);
        rtAttributeCardMapper.updateByPrimaryKey(rtAttributeCard);
    }

    private void checkIsCanUpdateOrDelete(RTAttributeCardDO currentDo) {
        String type = switchTypeToInnerName(currentDo.getType());
        List<String> partNumber = Collections.emptyList();
        if("EBOM_NUM".equals(type)){
            if(StringUtils.isBlank(currentDo.getDevelopmentOrder()) || StringUtils.isBlank(currentDo.getDevelopmentOrder())){
                partNumber = rtAttributeCardMapper.checkCurrentCardIfExistObj(currentDo.getProductLine(), currentDo.getDevelopmentOrder(),
                                                                              currentDo.getProductLine(), currentDo.getProductSeries(), type);
            }else {
                partNumber = rtAttributeCardMapper.checkCurrentCardIfExistObj(currentDo.getDevelopmentOrder(),
                                                                              currentDo.getDevelopmentOrder(),
                                                                              currentDo.getProductLine(), currentDo.getProductSeries(), type);
            }
        }else if("PatternCode".equals(type)){
            if(StringUtils.isBlank(currentDo.getDevelopmentOrder()) || StringUtils.isEmpty(currentDo.getDevelopmentOrder())){
                partNumber = rtAttributeCardMapper.checkCurrentCardIfExistObj(currentDo.getCategory(), currentDo.getProductLine(), "",
                                                                              currentDo.getProductSeries(), type);
            }else {
                partNumber = rtAttributeCardMapper.checkCurrentCardIfExistObj(currentDo.getCategory(), currentDo.getDevelopmentOrder(), "",
                                                                              currentDo.getProductSeries(), type);
            }
        } else if("Standard".equals(type)){
            partNumber = rtAttributeCardMapper.checkCurrentCardIfExistObj(currentDo.getCategory(), "","", "", type);
        }
        if (CollUtil.isNotEmpty(partNumber)) {
            throw  RTErrorCodeEnum.UPDATE_DESC_ERROR.getException("该属性卡片存在关联零部件，无法修改:"+String.join(",",partNumber));
        }
    }

    private String switchTypeToInnerName(String type) {
        String finalType = "";
        switch (type) {
            case "EBOM号":
                finalType = "EBOM_NUM";
                break;
            case "图样代号":
                finalType = "PatternCode";
                break;
            case "标准件":
                finalType = "Standard";
                break;
            case "物料码":
                finalType = "MaterialCode";
                break;
            default:
        }
        return finalType;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteAttrCard(List<BigInteger> oidList) {
        //1.获取对应的属性卡片分类OID
        for (BigInteger oid : oidList) {
            RTAttributeCardDO rtAttributeCardDO = rtAttributeCardMapper.selectByPrimaryKey(oid);
            checkIsCanUpdateOrDelete(rtAttributeCardDO);
        }
        oidList.forEach(
                item -> rtAttributeCardMapper.deleteByPrimaryKey(item)
        );
    }

    @Override
    public RTAttributeCardDO getDetailById(BigInteger oid) {
        return rtAttributeCardMapper.selectByPrimaryKey(oid);
    }

    @Override
    public List<String> getExtendAttributeByRTAttributeCardDO(RTAttributeCardDO rtAttributeCardDO, String typeName) {
        return rtAttributeCardMapper.getExtendAttributeByRTAttributeCardDO(rtAttributeCardDO,typeName);
    }

    @Override
    public PageInfo<RTAttributeCardDTO> list(QueryAttributeCardDTO dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<RTAttributeCardDTO> rtAttributeCards = rtAttributeCardMapper.list(dto.getDevelopmentOrder(), dto.getProductLine(),
                                                                               dto.getCategory(),
                                                                               dto.getAttributeCard(),
                                                                               dto.getType());
        return new PageInfo<>(rtAttributeCards);
    }

    @Override
    @Transactional
    public ClassificationDTO flexibleMatch(FlexibleMatchDTO dto) {
        String type = dto.getType();
        String category = dto.getCategory();
        String devCode = dto.getDevelopmentOrder();
        String patternCode = dto.getPatternCode();
        String productLine = dto.getProductLine();
        String productSeries = dto.getProductSeries();
        switch (type) {
            case "图样代号":
                return findDrawingCodeAttrCard(type, category, devCode, productSeries, productLine);
            case "物料码":
                if (StringUtils.isNotEmpty(patternCode)) {
                    // 根据 patternCode 查询分类classId
                    String classId=rtAttributeCardMapper.queryClassIdByPatternCode(patternCode);
                    //1.根据零部件编号查找开发令属性
                    BigInteger oid = rtAttributeCardMapper.queryPartId(patternCode);
                    if (ObjectUtil.isNull(oid)) {
                        throw RTErrorCodeEnum.PART_NOT_EXIST.getException("当前零部件不存在");
                    }
                    Map<String, List<AttributeVO>> ibaMaps = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                            Collections.singletonList(oid),
                            TableTypeConstrant.TY_PART_OTYPE,
                            Collections.singletonList(RTPlmConstant.DEVELOPMENT));
                    List<String> DevelopmentOrders = ibaMaps.values().stream()
                            .flatMap(List::stream)
                            .map(AttributeVO::getAttributeValue)
                            .filter(attributeValue -> StringUtils.isNotEmpty(String.valueOf(attributeValue)))
                            .distinct()
                            .collect(Collectors.toList());
                    if (CollUtil.isEmpty(DevelopmentOrders)) {
                        throw RTErrorCodeEnum.PART_DEV_NOT_EXIST.getException("当前零部件开发令不存在");
                    }

                    ClassificationDO classificationByOID = typlmClassificationService.getClassificationByOID(
                            new BigInteger(classId));

                    ClassificationDTO classificationDTO = BeanUtil.toBean(classificationByOID, ClassificationDTO.class);
                    classificationDTO.setDev(DevelopmentOrders.get(0));

                    Map<String, List<AttributeVO>> sb = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                            Collections.singletonList(oid),
                            TableTypeConstrant.TY_PART_OTYPE,
                            Collections.singletonList(RTPlmConstant.DESCRIPTION));
                    List<String> descriptionList = sb.values().stream()
                            .flatMap(List::stream)
                            .map(AttributeVO::getAttributeValue)
                            .filter(attributeValue -> StringUtils.isNotEmpty(String.valueOf(attributeValue)))
                            .distinct()
                            .collect(Collectors.toList());

                    if (CollUtil.isNotEmpty(descriptionList)) {
                        classificationDTO.setDescription(descriptionList.get(0));
                    }
                    classificationDTO.setPatternCode(patternCode);
                    return classificationDTO;
                } else {
                    throw RTErrorCodeEnum.TYPE_NOT_EXIST.getException("品类或图样代号为空");
                }

            case "EBOM号":
                return findEBOMAttrCard(devCode, type);
            case "标准件":
                // 校验品类是否存在
                if (StringUtils.isEmpty(category)) {
                    throw RTErrorCodeEnum.CLASSIFICATION_MATCH_INVALID_ERROR.getException("品类不能为空");
                }
                //根据开发令查询物料
                List<String> classIds = rtPartMapper.selectRefObjBaseOid(Collections.singletonList(category), "Standard");
                if(CollUtil.isNotEmpty(classIds) && classIds.size() == 1){
                    ClassificationDO classification = typlmClassificationService.getClassificationByOID(
                            new BigInteger(classIds.get(0)));
                    return BeanUtil.toBean(classification, ClassificationDTO.class);
                }
                if(classIds.size()>1){
                    throw RTErrorCodeEnum.CLASSIFICATION_NOT_UNIQUE_ERROR.getException("当前选择品类实例化对象的标准件所选属性卡片不唯一");
                }
                // 执行查询
                List<RTAttributeCardDO> stdCards = rtAttributeCardMapper.queryAttrCardByCategory(category, type);
                // 校验结果
                if (CollectionUtil.isEmpty(stdCards)) {
                    throw RTErrorCodeEnum.CLASSIFICATION_TYPE_ERROR.getException("当前未匹配到分类,请创建属性卡片");
                }
                if (stdCards.size() > 1) {
                    throw RTErrorCodeEnum.CLASSIFICATION_NOT_UNIQUE_ERROR.getException("当前属性卡片不唯一,请重新选择规则");
                }
                ClassificationDO classification = typlmClassificationService.getClassificationByOID(
                        new BigInteger(stdCards.get(0).getAttributeCard()));

                return BeanUtil.toBean(classification, ClassificationDTO.class);
        }
        throw RTErrorCodeEnum.CLASSIFICATION_TYPE_ERROR.getException("类型不存在");
    }

    private ClassificationDTO findDrawingCodeAttrCard(String type, String category, String devCode,
                                               String productSeries, String productLine) {
        // 品类+开发令匹配
        if (StringUtils.isNotEmpty(category) && StringUtils.isNotEmpty(devCode)) {
            List<String> partNumbers = Arrays.asList(category+"-"+devCode, category+"H"+devCode);
            List<String> classIds = rtPartMapper.selectRefObjBaseOid(partNumbers, "PatternCode");
            if(CollUtil.isNotEmpty(classIds) && classIds.size() == 1){
                ClassificationDO classification = typlmClassificationService.getClassificationByOID(
                        new BigInteger(classIds.get(0)));
                return BeanUtil.toBean(classification, ClassificationDTO.class);
            }
            if(classIds.size()>1){
                throw RTErrorCodeEnum.CLASSIFICATION_NOT_UNIQUE_ERROR.getException("当前选择开发令实例化对象的标准件所选属性卡片不唯一");
            }

            List<RTAttributeCardDO> matchedCards = rtAttributeCardMapper.designCodeFindMatchOne(type, category, devCode);
            if (isSingleMatch(matchedCards)) {
                return convertToClassificationDTO(matchedCards.get(0));
            }
        }

        // 品类+产品线+产品小类匹配
        if (StringUtils.isNotEmpty(category) && StringUtils.isNotEmpty(productSeries)) {
            List<RTAttributeCardDO> matchedCards = rtAttributeCardMapper.designCodeFindMatchTwo(type, category, productSeries, productLine);
            if (isSingleMatch(matchedCards)) {
                return convertToClassificationDTO(matchedCards.get(0));
            }
        }

        // 品类+产品线匹配
        if (StringUtils.isNotEmpty(category) && StringUtils.isNotEmpty(productLine)) {
            List<RTAttributeCardDO> matchedCards = rtAttributeCardMapper.designCodeFindMatchThree(type, category, productLine);
            if (isSingleMatch(matchedCards)) {
                return convertToClassificationDTO(matchedCards.get(0));
            }
        }

        // 仅品类匹配
        if (StringUtils.isNotEmpty(category)) {
            List<RTAttributeCardDO> matchedCards = rtAttributeCardMapper.designCodeFindMatchForth(type, category);
            if (isSingleMatch(matchedCards)) {
                return convertToClassificationDTO(matchedCards.get(0));
            }
        }

        throw RTErrorCodeEnum.CLASSIFICATION_TYPE_ERROR.getException("属性卡片匹配失败，请检查输入条件");
    }

    private ClassificationDTO convertToClassificationDTO(RTAttributeCardDO cardDO) {
        ClassificationDO classificationByOID = typlmClassificationService.getClassificationByOID(
                new BigInteger(cardDO.getAttributeCard()));
        return BeanUtil.toBean(classificationByOID, ClassificationDTO.class);
    }

    private boolean isSingleMatch(List<RTAttributeCardDO> matchedCards) {
        return CollectionUtil.isNotEmpty(matchedCards) && matchedCards.size() == 1;
    }

    private @NotNull ClassificationDTO findEBOMAttrCard(String devCode, String type) {
        // 校验开发令不能为空
        if (StringUtils.isEmpty(devCode)) {
            throw RTErrorCodeEnum.CLASSIFICATION_MATCH_INVALID_ERROR.getException("开发令不能为空");
        }
        //根据开发令查询物料
        List<String> classIds = rtPartMapper.selectRefObjBaseOid(Collections.singletonList(devCode), "EBOM_NUM");
        if(CollUtil.isNotEmpty(classIds) && classIds.size() == 1){
            ClassificationDO classification = typlmClassificationService.getClassificationByOID(
                    new BigInteger(classIds.get(0)));
           return BeanUtil.toBean(classification, ClassificationDTO.class);
        }
        if(classIds.size()>1){
            throw RTErrorCodeEnum.CLASSIFICATION_NOT_UNIQUE_ERROR.getException("当前选择开发令实例化对象的标准件所选属性卡片不唯一");
        }
        // 查询开发令对应的最新物料
        List<PartDO> partDOS = rtPartMapper.queryLatestMaterialByViewAndViewState(devCode, "", "");
        if (CollUtil.isEmpty(partDOS)) {
            throw RTErrorCodeEnum.PART_TYPE_NOT_EXIST.getException("开发令在系统中不存在");
        }
        PartDO partDO = partDOS.get(0);

        // 获取产品类型和产品系列属性
        String productType = "";
        String productSeries = "";
        Map<String, List<AttributeVO>> attrValueMap = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                Collections.singletonList(partDO.getOid()),
                TableTypeConstrant.TY_PART_OTYPE,
                Arrays.asList(RTPlmConstant.PRODUCTTYPE, "ProductSeries")
        );

        if (CollUtil.isNotEmpty(attrValueMap)) {
            List<AttributeVO> attributeVOS = attrValueMap.get(String.valueOf(partDO.getOid()));
            if (CollUtil.isNotEmpty(attributeVOS)) {
                for (AttributeVO attributeVO : attributeVOS) {
                    String attrName = attributeVO.getAttributeEnName();
                    String attrValue = StringUtils.isBlank(attributeVO.getAttributeValuex())
                            ? attributeVO.getAttributeValue()
                            : attributeVO.getAttributeValuex();

                    if (RTPlmConstant.PRODUCTTYPE.equals(attrName)) {
                        productType = attrValue;
                    } else if ("ProductSeries".equals(attrName)) {
                        productSeries = attrValue;
                    }
                }
            }
        }

        // 提取线体编码（取开发令首字符）
        String lineCode = devCode.substring(0, 1);
        String classId = null;

        // 分层次查询属性卡片OID
        // 1. 优先通过开发令直接查询
        List<RTAttributeCardDO> devCards = rtAttributeCardMapper.findEBOMCardFirst(type, devCode);
        if (CollectionUtil.isNotEmpty(devCards) && devCards.size() == 1) {
            classId = devCards.get(0).getAttributeCard();
        }
        // 2. 其次通过产品系列、线体编码查询
        else if (StringUtils.isNotBlank(productSeries) && StringUtils.isNotBlank(productType)) {
            List<RTAttributeCardDO> seriesCards = rtAttributeCardMapper.findEBOMCardSecond(productSeries, lineCode,
                                                                                           type);
            if (CollectionUtil.isNotEmpty(seriesCards) && seriesCards.size() == 1) {
                classId = seriesCards.get(0).getAttributeCard();
            }
            // 3. 最后通过线体编码查询
            else if (StringUtils.isNotBlank(lineCode)) {
                List<RTAttributeCardDO> lineCards = rtAttributeCardMapper.findEBOMCardThird(lineCode, type);
                if (CollectionUtil.isNotEmpty(lineCards) && lineCards.size() == 1) {
                    classId = lineCards.get(0).getAttributeCard();
                }
            }
        } else if (StringUtils.isNotBlank(lineCode)) {
            List<RTAttributeCardDO> lineCards = rtAttributeCardMapper.findEBOMCardThird(lineCode, type);
            if (CollectionUtil.isNotEmpty(lineCards) && lineCards.size() == 1) {
                classId = lineCards.get(0).getAttributeCard();
            }
        }

        // 校验卡片查询结果
        if (classId == null) {
            throw RTErrorCodeEnum.CLASSIFICATION_NOT_UNIQUE_ERROR.getException("属性卡片命中失败，请检查配置规则");
        }

        // 转换并返回分类信息
        ClassificationDO classificationDO = typlmClassificationService.getClassificationByOID(new BigInteger(classId));
        ClassificationDTO classificationDTO = BeanUtil.toBean(classificationDO, ClassificationDTO.class);
        classificationDTO.setProductType(productType);
        return classificationDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void createIbaAttribute(List<AttributeCardDTO> attributeList, BigInteger ibaGroupId) {
        UserDO userDO = TyAccountContext.getUser();
        for (AttributeCardDTO cardDTO : attributeList) {
            AttributeDefDTO attributeDefDTO = new AttributeDefDTO();
            attributeDefDTO.setName(cardDTO.getAttributeInName());
            attributeDefDTO.setAttributegroupoid(ibaGroupId);
            attributeDefDTO.setAttributegroupotype(TableTypeConstrant.TY_ATTRIBUTEGROUP_OTYPE);
            attributeDefDTO.setDescription(cardDTO.getIsSplice());
            attributeDefDTO.setDisplayname(cardDTO.getAttributeDisName());
            attributeDefDTO.setOtype(TableTypeConstrant.TY_STRINGDEF_OTYPE);
            typlmAttributeDefService.createAttrDef(attributeDefDTO, userDO);
        }
    }


    @Override
    public List<TyplmClassificationEntityTreeVO> queryAttrClassificationTree(String typeName, String categoryCode) {
        log.info("============提示信息==============> 查询属性分类树:{}",typeName);
        List<TyplmClassificationEntityDTO> classRootDTOList = this.typlmClassificationRootService.queryClassificationRootByLanguage();
        List<TyplmClassificationEntityDTO> partClassRoot = classRootDTOList.stream().filter(item -> ("零部件").equals(item.getDisplayName())).collect(Collectors.toList());
        String rootId = partClassRoot.get(0).getId();
        List<TyplmClassificationEntityDTO> classificationEntityDTOS =typlmClassificationService.queryClassificationByRoot(rootId);
        if(typeName.equals("EBOM号")){
            TyplmClassificationEntityDTO classificationEntityDTO = classificationEntityDTOS.stream()
                    .filter(dto ->"product".equals(dto.getInternalName()))
                    .findFirst()
                    .orElse(null);
            if (ObjectUtil.isNull(classificationEntityDTO)){
                throw  RTErrorCodeEnum.CLASSIFICATION_NOT_EXIST.getException("类型:产品不存在!");
            }
            TyplmClassificationQueryTreeDTO typlmClassificationQueryTreeDTO = new TyplmClassificationQueryTreeDTO();
            typlmClassificationQueryTreeDTO.setOid(new BigInteger(classificationEntityDTO.getId()));
            typlmClassificationQueryTreeDTO.setOtype(TableTypeConstrant.TY_CLASSIFICATION_OTYPE);
            typlmClassificationQueryTreeDTO.setTypeOid(new BigInteger(classificationEntityDTO.getId()));
            List<TyplmClassificationEntityTreeVO> typlmClassificationEntityTreeVOS = typlmClassificationService.queryClassificationTree(
                    typlmClassificationQueryTreeDTO);
            TyplmClassificationEntityTreeVO typlmClassificationEntityTreeVO = typlmClassificationEntityTreeVOS.get(0);
            List<TyplmClassificationEntityTreeVO> children = new ArrayList<>();
            List<String> classIds = rtTypeClassMapper.queryClassIdByName("L", categoryCode);
            dealClassChildren(typlmClassificationEntityTreeVO, children, classIds);
            typlmClassificationEntityTreeVO.setChildren(children);
            return Collections.singletonList(typlmClassificationEntityTreeVO);
        } else {
            TyplmClassificationEntityDTO classificationEntityDTO = classificationEntityDTOS.stream()
                    .filter(dto ->"产品分类".equals(dto.getInternalName()))
                    .findFirst()
                    .orElse(null);
            if (ObjectUtil.isNull(classificationEntityDTO)){
                throw  RTErrorCodeEnum.CLASSIFICATION_NOT_EXIST.getException("类型:编码不存在!");
            }

            TyplmClassificationQueryTreeDTO typlmClassificationQueryTreeDTO = new TyplmClassificationQueryTreeDTO();
            typlmClassificationQueryTreeDTO.setOid(new BigInteger(classificationEntityDTO.getId()));
            typlmClassificationQueryTreeDTO.setOtype(TableTypeConstrant.TY_CLASSIFICATION_OTYPE);
            typlmClassificationQueryTreeDTO.setTypeOid(new BigInteger(classificationEntityDTO.getId()));
            List<TyplmClassificationEntityTreeVO> typlmClassificationEntityTreeVOS = typlmClassificationService.queryClassificationTree(
                    typlmClassificationQueryTreeDTO);
            TyplmClassificationEntityTreeVO typlmClassificationEntityTreeVO = typlmClassificationEntityTreeVOS.get(0);
            List<TyplmClassificationEntityTreeVO> children = new ArrayList<>();
            if("图样代号".equals(typeName)){
                typeName = "T";
            } else if("物料码".equals(typeName)){
                typeName = "W";
            } else if("标准件".equals(typeName)){
                typeName = "B";
            }

            List<String> classIds = rtTypeClassMapper.queryClassIdByName(typeName, categoryCode);
            dealClassChildren(typlmClassificationEntityTreeVO, children, classIds);
            typlmClassificationEntityTreeVO.setChildren(children);
            return Collections.singletonList(typlmClassificationEntityTreeVO);
        }
    }

    private void dealClassChildren(TyplmClassificationEntityTreeVO treeVO,
                                   List<TyplmClassificationEntityTreeVO> children, List<String> classIds) {
        if (classIds.contains(String.valueOf(treeVO.getId()))) {
            children.add(treeVO);
        } else if (CollUtil.isNotEmpty(treeVO.getChildren())) {
            for (TyplmClassificationEntityTreeVO child : treeVO.getChildren()) {
                dealClassChildren(child, children, classIds);
            }
        }
    }

    @Override
    public List<DrawingCodeVO> queryDrawingCode(String key) {
        if(StringUtils.isNotEmpty(key) && StringUtils.isNotBlank(key)){
            String[] split = key.split(" ");
            List<String> keys = new ArrayList<>(Arrays.asList(split));
            return rtPartMapper.selectDrawingCodeByKey(keys);
        }
        return rtPartMapper.selectDrawingCode();
    }

    @Override
    public List<TypeTree> queryTypeTreeByOid() {
        List<TypeTree> typeTrees = rtAttributeCardMapper.queryTypeTreeByOid(new BigInteger(typeOId));

        //2.把该分类父OID设置为0，约定作为标记为顶层父类
        if (CollUtil.isNotEmpty(typeTrees)) {
            typeTrees.forEach((item) -> {
                if (new BigInteger(typeOId).equals(item.getOid())) {
                    item.setParentnodeoid(BigInteger.ZERO);
                }
            });
        }

        return list2treeV2(typeTrees);

    }

    //3.扁平列表递归转树
    private  List<TypeTree> list2treeV2(List<TypeTree> typeTrees) {
        if (CollUtil.isEmpty(typeTrees)) {
            return new ArrayList<>();
        }
        // 父ID → 子节点列表”
        Map<BigInteger, List<TypeTree>> treeMap = typeTrees.stream().collect(Collectors.groupingBy(TypeTree::getParentnodeoid));

        List<TypeTree> root =  treeMap.get(BigInteger.ZERO);
        if (CollUtil.isNotEmpty(root)) {
            root.forEach((entity) -> {
                setChildren(treeMap, entity);
            });
        }
        return root != null ? root : new ArrayList<>();
    }

    private  void setChildren(Map<BigInteger, List<TypeTree>> treeMap, TypeTree entity) {
        BigInteger oid = entity.getOid();
        List<TypeTree> children = treeMap.get(oid);
        if (CollUtil.isEmpty(children)) {
            entity.setChildList(new ArrayList<>());
            return;
        }
        entity.setChildList(children);
        children.forEach((child) -> {
            setChildren(treeMap, child);
        });
    }

    @Override
    public List<RTCodeVO> queryCode(RTCodeVO postdata) {
        return rtPartMapper.queryCode(postdata);
    }

    @Override
    public List<Map<String, Object>> queryCategoryCodeAndName() {
        return rtPartMapper.queryCategoryCodeAndName();
    }

    @Override
    public PageInfo<String> selectAllCode(Integer PageNum,Integer PageSize,String keyWork) {
        PageHelper.startPage(PageNum,PageSize);
        List<String> list=rtAttributeCardMapper.selectAllCode(keyWork);
        PageInfo<String> stringPageInfo = new PageInfo<>(list);
        return stringPageInfo;
    }

    @Override
    public List<String> queryProductSubcategory(String productLine) {
        return rtAttributeCardMapper.queryProductSubcategory(productLine);
    }
}


